﻿using System;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Threading.Tasks;
using YiSha.Util;
using YiSha.Util.Extension;
using YiSha.Util.Model;
using YiSha.Data;
using YiSha.Data.Repository;
using YiSha.Entity.YiDongYuan;
using YiSha.Model.Param.YiDongYuan;
using YiSha.Model.Param.YiDongYuan.Hzx;

namespace YiSha.Service.YiDongYuan
{
    /// <summary>
    /// 创 建：admin
    /// 日 期：2021-06-09 08:20
    /// 描 述：检测任务服务类
    /// </summary>
    public class DetectionTaskService : RepositoryFactory
    {
        private MechanicsService mechanicsService = new MechanicsService();

        #region 获取数据

        public async Task<List<RegionReportEntity>> GetRegionList(string type)
        {
            var strSql = new StringBuilder();
            strSql.Append("SELECT Region as RegionName,COUNT(*) as RegionValue FROM detectiontask where detectionStatus=1 ");
            switch (type)
            {
                case "month":
                    strSql.Append(" and DATE_FORMAT(DetectionTime, '%y-%m')=DATE_FORMAT(NOW(),'%y-%m') ");
                    break;

                case "today":
                    strSql.Append(" and DATE_FORMAT(DetectionTime, '%y-%m-%d')=DATE_FORMAT(NOW(),'%y-%m-%d') ");
                    break;
            }
            strSql.Append(" GROUP BY region ORDER BY COUNT(*) DESC");
            var list = await this.BaseRepository().FindList<RegionReportEntity>(strSql.ToString());
            return list.ToList();
        }

        public async Task<List<ProcessDataEntity>> GetListByInfoId(long id)
        {
            string sql = string.Format(@"SELECT data FROM detectionresultdata
                      WHERE ResultId=(
                     SELECT ResultDataId FROM detectioninfo WHERE id=" + id + ")");
            var result = await this.BaseRepository().FindObject(sql);
            var list = new List<ProcessDataEntity>();
            if (result != null)
            {
                foreach (string item in result.ToString().Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string[] item2 = item.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                    if (item2[1] == "0")
                    {
                        continue;
                    }
                    list.Add(new ProcessDataEntity()
                    {
                        Time = item2[0],
                        Index = item2[1],
                        Speed = item2[2],
                        NValue = item2[3],
                        KValue = item2[4]
                    });
                }
            }
            return list;
        }

        public async Task<List<DetectionTaskEntity>> GetList(DetectionTaskListParam param)
        {
            var expression = ListFilter(param);
            var list = await this.BaseRepository().FindList(expression);
            return list.ToList();
        }

        public async Task<List<DetectionTaskEntity>> GetListByUserId(long userId)
        {
            var expression = ListFilter(null);
            expression = expression.And(t => t.DetectionUserId == userId);
            var list = await this.BaseRepository().FindList(expression);
            return list.ToList();
        }

        public async Task<List<DetectionTaskEntity>> GetPageList(DetectionTaskListParam param, Pagination pagination)
        {
            var expression = ListFilter(param);
            var list = await this.BaseRepository().FindList(expression, pagination);
            return list.ToList();
        }

        public async Task<DetectionTaskEntity> GetEntity(long id)
        {
            return await this.BaseRepository().FindEntity<DetectionTaskEntity>(id);
        }

        public async Task<long> GetRecheclCount(int detectionType)
        {
            StringBuilder strSql = new StringBuilder("SELECT COUNT(*) FROM detectiontask WHERE DetectionType=" + detectionType);
            return (long)await this.BaseRepository().FindObject(strSql.ToString());
        }

        public async Task<DetectionTaskEntity> GetLastEntityByCode(string code)
        {
            var list = await this.BaseRepository().FindList<DetectionTaskEntity>(t => t.HuanBaoCode == code && t.DetectionStatus == 1 && t.AuditStatus == 1);
            return list.OrderByDescending(t => t.DetectionTime).FirstOrDefault();
        }

        #endregion 获取数据

        #region 提交数据

        public async Task SaveForm(DetectionTaskEntity entity)
        {
            if (entity.Id.IsNullOrZero())
            {
                await entity.Create();
                await this.BaseRepository().Insert(entity);
            }
            else
            {
                await this.BaseRepository().Update(entity);
            }
        }

        public async Task DeleteForm(string ids)
        {
            long[] idArr = TextHelper.SplitToArray<long>(ids, ',');
            await this.BaseRepository().Delete<DetectionTaskEntity>(idArr);
        }

        public async Task Audit(string id, int auditStatus, string auditReason, long? auditUserId)
        {
            await this.BaseRepository().BeginTrans();
            try
            {
                var entity = await this.GetEntity(id.ParseToLong());

                entity.AuditReason = auditReason;
                entity.AuditTime = DateTime.Now;
                entity.AuditUserId = auditUserId;
                entity.AuditStatus = auditStatus;
                if (auditStatus == 9)
                {
                    entity.DetectionStatus = 0;
                }
                await this.BaseRepository().Update(entity);
                DetectionInfoEntity infoEntity = await this.BaseRepository().FindEntity<DetectionInfoEntity>(t => t.Id == entity.DetectionInfoId.Value);
                DetectionMechanicsEntity detectionMechanicsEntity = await this.BaseRepository().FindEntity<DetectionMechanicsEntity>(t => t.Id == entity.MechanicsId.Value);
                detectionMechanicsEntity.GpsNo = infoEntity.GpsNo;
                MechanicsEntity mechanicsEntity = await this.BaseRepository().FindEntity<MechanicsEntity>(t => t.HuanBaoCode == detectionMechanicsEntity.HuanBaoCode);
                if (mechanicsEntity == null)
                {
                    mechanicsEntity = new MechanicsEntity();
                    mechanicsEntity.CopyFromDetectionMechanics(detectionMechanicsEntity);
                    await mechanicsEntity.Create();
                    await this.BaseRepository().Insert(mechanicsEntity);
                }
                else
                {
                    mechanicsEntity.CopyFromDetectionMechanics(detectionMechanicsEntity);
                    await this.BaseRepository().Update(mechanicsEntity);
                }
                await this.BaseRepository().Update(detectionMechanicsEntity);
                await this.BaseRepository().CommitTrans();
                //if (auditStatus == 1)
                //{
                //    new Task(() =>
                //    {
                //        DoUp2Hzx(id.ParseToLong());
                //    }).Start();
                //}
            }
            catch (Exception)
            {
                await this.BaseRepository().RollbackTrans();
                throw;
            }
        }

        public async Task SaveRecheckForm(RecheckEntity entity)
        {
            await this.BaseRepository().BeginTrans();
            try
            {
                //查询mechaincs
                MechanicsEntity mechanics = mechanicsService.GetEntity(entity.HuanBaoCode).Result;
                DetectionMechanicsEntity detectionMechanicsEntity = new DetectionMechanicsEntity();
                if (mechanics != null)
                {
                    detectionMechanicsEntity.CopyFromMechanics(mechanics);
                }
                else
                {
                    //如果不存在 创建detectionMechanics
                    detectionMechanicsEntity.OwnerName = entity.OwnerName;
                    detectionMechanicsEntity.OwnerTel = entity.OwnerTel;
                    detectionMechanicsEntity.HuanBaoCode = entity.HuanBaoCode;
                }
                await detectionMechanicsEntity.Create();
                await this.BaseRepository().Insert(detectionMechanicsEntity);
                //创建 detectionTask
                DetectionTaskEntity taskEntity = new DetectionTaskEntity()//复检任务
                {
                    DetectionType = 1,
                    Region = entity.Region,
                    HuanBaoCode = entity.HuanBaoCode,
                    DetectionUserId = entity.DetectionUserId,
                    DetectionStatus = 0,
                    AuditStatus = -1,
                    MechanicsId = detectionMechanicsEntity.Id
                };
                await taskEntity.Create();
                await this.BaseRepository().Insert(taskEntity);
                await this.BaseRepository().CommitTrans();
            }
            catch (Exception)
            {
                await this.BaseRepository().RollbackTrans();
                throw;
            }
        }

        public async Task SaveChangeCode(long id, string newCode)
        {
            var db = this.BaseRepository();
            try
            {
                await db.BeginTrans();
                var plate = db.IQueryable<SparePlateEntity>(t => t.HuanBaoCode == newCode).FirstOrDefault();
                if (plate == null)
                    throw new Exception("该环保号牌已被使用");
                var detectionTask = db.IQueryable<DetectionTaskEntity>(t => t.Id == id).FirstOrDefault();
                var detectionMechanics = db.IQueryable<DetectionMechanicsEntity>(t => t.Id == detectionTask.MechanicsId).FirstOrDefault();
                var mechanics = db.IQueryable<MechanicsEntity>(t => t.HuanBaoCode == detectionMechanics.HuanBaoCode).FirstOrDefault();
                //更改检测任务表
                detectionTask.HuanBaoCode = newCode;
                await db.Update(detectionTask);
                //更改检测机械档案表
                detectionMechanics.HuanBaoCode = newCode;
                await db.Update(detectionMechanics);
                //更改机械档案表
                mechanics.HuanBaoCode = newCode;
                await db.Update(mechanics);
                //删除库存号牌表
                await db.Delete(plate);
                await db.CommitTrans();
                //todo:需要上传吗
            }
            catch (Exception)
            {
                await db.RollbackTrans();
                throw;
            }
        }

        public void Upload2Hzx(long id)
        {
            DoUp2Hzx(id);
        }

        #endregion 提交数据

        #region 私有方法

        private Expression<Func<DetectionTaskEntity, bool>> ListFilter(DetectionTaskListParam param)
        {
            var expression = LinqExtensions.True<DetectionTaskEntity>();
            if (param != null)
            {
                //if (param.AuditStatus != -1)
                //{
                //    expression = expression.And(t => t.AuditStatus == param.AuditStatus);
                //}
                if (!param.Region.IsNullOrEmpty() && !param.Region.Equals("运城市"))
                {
                    expression = expression.And(t => t.Region == param.Region);
                }
                if (!param.keywords.IsNullOrEmpty())
                {
                    expression = expression.And(t => t.HuanBaoCode.Contains(param.keywords));
                }
                if (param.DetectionStatus != -1)
                {
                    expression = expression.And(t => t.DetectionStatus == param.DetectionStatus);
                }
                if (param.DetectionType != -1)
                {
                    expression = expression.And(t => t.DetectionType == param.DetectionType);
                }
            }
            return expression;
        }

        #endregion 私有方法

        #region 上传华志信

        public async void DoUp2Hzx(long detectionTaskId)
        {
            var db = this.BaseRepository();
            try
            {
                var model = db.IQueryable<DetectionTaskEntity>(t => t.Id == detectionTaskId).SingleOrDefault();
                if (model.IsUp2Hzx == 1)
                {
                    throw new Exception("已上传成功，请勿重复操作");
                }
                var mechanics = db.IQueryable<DetectionMechanicsEntity>(t => t.Id == model.MechanicsId).SingleOrDefault();
                var check = db.IQueryable<DetectionInfoEntity>(t => t.Id == model.DetectionInfoId).FirstOrDefault();
                DetectionResultEntity wqjc = null;
                if (!(mechanics.JXDJLX.Contains("电动") || mechanics.PFJD.Contains("D")))
                {
                    if (check == null)
                    {
                        LogHelper.Info($"{model.HuanBaoCode}-{model.Id}没有找到checkresult");
                    }
                    else
                    {
                        wqjc = db.IQueryable<DetectionResultEntity>(t => t.Id == check.ResultDataId).SingleOrDefault();
                    }
                }
                if (DoUp2Hzx(model, mechanics, wqjc, check))
                {
                    model.IsUp2Hzx = 1;
                    await db.Update(model);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"{detectionTaskId}出错：" + ex.Message, ex);
            }
        }

        private bool DoUp2Hzx(DetectionTaskEntity model, DetectionMechanicsEntity mechanics, DetectionResultEntity wqjc, DetectionInfoEntity check)
        {
            LogHelper.Info("开始上传华志信待检数据");
            var uploadService = new Upload2Hzx();
            uploadService.UploadMechanics(mechanics);
            if (wqjc != null)
            {
                //获取检测任务id
                string id = uploadService.UploadTask(new Hzx_Reservation()
                {
                    address = check.Address,
                    certificateNum = "200405340887",
                    codeNum = model.HuanBaoCode,
                    contacts = mechanics.OwnerName,
                    contactsnum = mechanics.OwnerTel,
                    testDate = model.DetectionTime.Value.GetDateTimeFormats('s')[0]
                });
                if (!id.IsLong())
                {
                    return false;
                }
                //上传检测数据
                Hzx_TestResult testResult = new Hzx_TestResult()
                {
                    testId = id,
                    billCode = check.BillNo,
                    aveResult = wqjc.accavg,
                    limitResult = wqjc.acclimits,
                    methodType = 1,
                    num = "200792",
                    result = wqjc.testresult.ParseToInt(),
                    rotateSpeed1 = wqjc.Rpm1.ParseToInt(),
                    rotateSpeed2 = wqjc.Rpm2.ParseToInt(),
                    rotateSpeed3 = wqjc.Rpm3.ParseToInt(),
                    testAddress = check.Address,
                    testDate = model.DetectionTime.Value.GetDateTimeFormats('s')[0],
                    testResult1 = wqjc.k1,
                    testResult2 = wqjc.k2,
                    testResult3 = wqjc.k3,
                    videoId = check.VideoId.ToString()
                };
                string result = uploadService.UploadTestResult(testResult);
                if (result.Contains("200"))
                {
                    return true;
                }
            }
            else
            {
                LogHelper.Info("wqjc是空，不上传检测数据");
            }
            return false;
        }

        #endregion 上传华志信
    }
}
